package com.hui.stock.sharding;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.joda.time.DateTime;

import java.util.Collection;
import java.util.Date;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author: ymh
 * @date: 2025/1/6 15:38
 * @description: 公共的分库算法类：覆盖个股 大盘 板块相关表
 */
public class CommonAlg4Db implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Date> {

    /**
     * 精准查询
     * 分库策略：按年分库
     * 精准查询：分片键 cur_time
     * eg:
     * @param dsNames ds-2021 ds-2022 ds-2023
     * @param shardingValue
     * @return
     */
    @Override
    public String doSharding(Collection<String> dsNames, PreciseShardingValue<Date> shardingValue) {
        //1 获取逻辑表
        String logicTableName = shardingValue.getLogicTableName();
        //2 获取分片键
        String curTime = shardingValue.getColumnName();
        //3 获取条件值
        Date date = shardingValue.getValue();
        //4 封装条件值的年份数据
        String year = new DateTime(date).getYear() + "";
        //5 过滤数据源中符合条件的
        Optional<String> result = dsNames.stream().filter(dsName -> dsName.substring(dsName.indexOf("-") + 1).equals(year)).findFirst();
        return result.orElse(null);
    }

    /**
     * 范围查询
     * eg:2021---2022
     * @param dsNames ds-2021 ds-2022 ds-2023
     * @param shardingValue
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> dsNames, RangeShardingValue<Date> shardingValue) {
        //1 获取逻辑表
        String logicTableName = shardingValue.getLogicTableName();
        //2 获取分片键
        String curTime = shardingValue.getColumnName();
        //3 判断下限
        if (shardingValue.getValueRange().hasLowerBound()) {
            Date startDate = shardingValue.getValueRange().lowerEndpoint();
            int startYear = new DateTime(startDate).getYear();
            //过滤出比下限高的
            dsNames = dsNames.stream().filter(dsName -> Integer.parseInt(dsName.substring(dsName.indexOf("-") + 1))>=startYear).collect(Collectors.toList());
        }
        //4 判断上限
        if (shardingValue.getValueRange().hasUpperBound()) {
            Date startDate = shardingValue.getValueRange().upperEndpoint();
            int endYear = new DateTime(startDate).getYear();
            //过滤出比下限高的
            dsNames = dsNames.stream().filter(dsName -> Integer.parseInt(dsName.substring(dsName.indexOf("-") + 1))<=endYear).collect(Collectors.toList());
        }
        return dsNames;
    }
}
